package net.asrsmid.connection.as;

import java.util.List;
import java.util.Locale;

import net.asrsmid.connection.AsRsPoolableConnection;

import org.olap4j.CellSet;
import org.olap4j.OlapConnection;
import org.olap4j.OlapDatabaseMetaData;
import org.olap4j.OlapException;
import org.olap4j.OlapStatement;
import org.olap4j.metadata.Catalog;
import org.olap4j.metadata.Cube;
import org.olap4j.metadata.Database;
import org.olap4j.metadata.Dimension;
import org.olap4j.metadata.Hierarchy;
import org.olap4j.metadata.Level;
import org.olap4j.metadata.Member;
import org.olap4j.metadata.NamedList;
import org.olap4j.metadata.Property;
import org.olap4j.metadata.Schema;


/**
 * public class AsOlapConnection<br>
 * extends {@link AsRsPoolableConnection} implements {@link OlapConnection}<br>
 * AsOlapConnection is a poolable wrapper class of OlapConnection
 * @author Chen WANG
 * @since 05-mai-2011
 */
//public class AsOlapConnection extends AsRsPoolableConnection implements OlapConnection {
public class AsOlapConnection extends AsRsPoolableConnection {
	private OlapConnection conn;

	/**
	 * Constructs an OlapConnection wrapper object
	 * @param conn olap connection to wrapper
	 */
	public AsOlapConnection(OlapConnection conn) {
		this.conn = conn;
	}

	/**
	 * release the connection and return it to pool
	 */
	public void release() {
		if (conn != null) {
			try {
				//if (!conn.isClosed()) conn.close();
				pool.returnObject(this);
			} catch (Exception e) {
				// error when returning connection to pool 
				e.printStackTrace();
			}
		}
	}
	
	public OlapConnection unwrap() {
		return conn;
	}

	public CellSet executeMdxQuery(String mdxQuery) {
		CellSet cs = null;
		try {
			OlapStatement st = conn.createStatement();
			cs = st.executeOlapQuery(mdxQuery);
			st.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return cs;
	}

	public String getRoleName() {
		return conn.getRoleName();
	}
	
	public List<String> getAvailableRoleNames() throws OlapException {
		return conn.getAvailableRoleNames();
	}

	public String getCatalogName() throws OlapException {
		return conn.getCatalog();
	}

	public Catalog getCatalog() throws OlapException {
		return conn.getOlapCatalog();
	}
	
	public NamedList<Catalog> getCatalogs() throws OlapException {
		return conn.getOlapCatalogs();
	}

	public String getDatabaseName() throws OlapException {
		return conn.getDatabase();
	}

	public Database getOlapDatabase() throws OlapException {
		return conn.getOlapDatabase();
	}
	
	public NamedList<Database> getDatabases() throws OlapException {
		return conn.getOlapDatabases();
	}
	
	public Locale getLocale() {
		return conn.getLocale();
	}

	public OlapDatabaseMetaData getMetaData() throws OlapException {
		return conn.getMetaData();
	}
	
	public Cube getCube(String cubeName) throws OlapException {
		NamedList<Schema> shemas = conn.getOlapCatalog().getSchemas();
		NamedList<Cube> cubes = shemas.get("").getCubes();
		Cube cube = null;
		if (cubeName == null) 
			cube = cubes.get(0);
		else
			cube = cubes.get(cubeName);
		return cube;
	}
	
	public Cube getCube() throws OlapException {
		return getCube(null);
	}
	
	public NamedList<Dimension> getDimensions(String cubeName) throws OlapException {
		Cube cube = getCube(cubeName);
		NamedList<Dimension> dimensions = cube.getDimensions();
		return dimensions;
	}
	
	public Dimension getDimension(String cubeName, String dimensionName) throws OlapException {
		return getDimensions(cubeName).get(dimensionName);
	}
	
	public NamedList<Hierarchy> getHierarchies(String cubeName, String dimensionName) throws OlapException {
		Dimension dimension = getDimension(cubeName, dimensionName);
		NamedList<Hierarchy> hierarchies = dimension.getHierarchies();
		return hierarchies;
	}
	
	public Hierarchy getHierarchy(String cubeName, String dimensionName, String hierarchyName) throws OlapException {
		return getHierarchies(cubeName, dimensionName).get(hierarchyName);
	}
	
	public NamedList<Level> getLevels(String cubeName, String dimensionName, String hierarchyName) throws OlapException {
		Hierarchy hierarchy = getHierarchy(cubeName, dimensionName, hierarchyName);
		NamedList<Level> levels = hierarchy.getLevels();
		return levels;
	}
	
	public Level getLevel(String cubeName, String dimensionName, String hierarchyName, String levelName) throws OlapException {
		return getLevels(cubeName, dimensionName, hierarchyName).get(levelName);
	}
	
	public NamedList<Property> getProperties(String cubeName, String dimensionName, String hierarchyName, String levelName) throws OlapException {
		Level level = getLevel(cubeName, dimensionName, hierarchyName, levelName);
		NamedList<Property> properties = level.getProperties();
		return properties;
	}
	
	public Property getProperty(String cubeName, String dimensionName, String hierarchyName, String levelName, String propertyName) throws OlapException {
		return getProperties(cubeName, dimensionName, hierarchyName, levelName).get(propertyName);
	}
	
	public List<Member> getMembers(String cubeName, String dimensionName, String hierarchyName, String levelName) throws OlapException {
		Level level = getLevel(cubeName, dimensionName, hierarchyName, levelName);
		List<Member> members = level.getMembers();
		return members;
	}
}